package com.mmall.Concurrency.example.singleton;

/*
    懒汉模式，双重同步锁单例模式
    一开始懒得创建
 */

import com.mmall.Concurrency.annoations.NotRecommend;
import com.mmall.Concurrency.annoations.NotThreadSafe;
import com.mmall.Concurrency.annoations.ThreadSafe;

/*
   instance = new SingletonExample1();
   多线程下运行两次，可能导致两次调用构造函数（如果中间有运算或者对资源的调用，则可能不适合，线程不安全）
 */
@NotThreadSafe
@NotRecommend
public class SingletonExample4 {

    //不能随便new新的对象出来，则构造方法为私有的
    private SingletonExample4() {

    }

    /**
     * 1.memory = allocate()分配对象的内存空间
     * 2.ctorInstance()初始化对象
     * 3.instance = memory 设置instance指向刚分配的内存
     */
    /**
     * 指令重排的时候
     * 1.memory = allocate()分配对象的内存空间
     * 2.instance = memory 设置instance指向刚分配的内存
     * 3.ctorInstance()初始化对象
     *
     */

    //单例对象
    private static SingletonExample4 instance = null;

    //静态的工厂方法
    //只允许一个访问，性能下降，放在方法修饰上不好，下沉在方法实现里面去
    private static SingletonExample4 getInstance() {  //里面所有的实现，能保证只允许一个线程访问
        if (instance == null) {   //双重检测机制  //B  在A指向后，发现有值则直接返回，但是初始化对象这一步还没做，会出错
            synchronized (SingletonExample4.class) {//判断之后，单独锁这个类
                if (instance == null) {
                    instance = new SingletonExample4();  //A   --3指向分配的内存
                }
            }
        }

        return instance;
    }
}
